﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace BaseArith {
    /// <summary>
    /// 数列
    /// </summary>
    public static class Progression {
        #region 数列
        /// <summary>
        /// 费波那西数列由 0 和 1 开始，之后的费波那西系数就由之前的两数相加
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public static int[] FibonacciBuild(byte count) {
            var r = new int[count];
            r[0] = r[1] = 1;
            for (int i = 2 ; i < count ; i++) {
                r[i] = r[i - 2] + r[i - 1];
            }
            return r;
        }
        public static long FibonacciIndexValue(byte length) {
            var r = default(long);
            if (length == 0) return 1;
            if (length == 1) return 1;
            r += FibonacciIndexValue((byte)(length - 2)) + FibonacciIndexValue((byte)(length - 1));
            return r;
        }

        public static long FibonacciSum(byte length) {
            var r = default(long);
            if (length == 0) return 1;
            if (length == 1) return 1;
            for (int i = length ; i > 2 ; i--) {
                r += FibonacciIndexValue((byte)(i - 2)) + FibonacciIndexValue((byte)(length - 1));
            }
            return r;
        }
        public static float[] EqualDifferenceBuild(byte count,float diff,float iniv = 0) {
            var r = new float[count];
            r[0] = iniv;
            for (int i = 0 ; i < count ; i++) {
                r[i] += diff;
            }
            return r;
        }
        public static double EqualDifferenceIndexValue(byte len,float diff,float iniv = 0) {
            var r = default(double);
            if (len == 0) {
                r = iniv;
            } else {
                r += diff;
                r += EqualDifferenceIndexValue((byte)(len - 1),diff,iniv);
            }
            return r;
        }
        /// <summary>
        /// 一般数列表达式
        /// </summary>
        /// <param name="len">长度</param>
        /// <param name="func">下项公式</param>
        /// <param name="iniv">初值</param>
        /// <returns></returns>
        public static float[] GeneraicSeqenceBuild(byte len,Func<float,float> func,float iniv = 0) {
            var r = new float[len];
            var len2 = len - 1;
            r[0] = iniv;
            for (int i = 1 ; i < len2 ; i++) {
                r[i] = func(r[i - 1]);
            }
            return r;
        }
        /// <summary>
        /// 返回指定索引处的数列值
        /// </summary>
        /// <param name="index">索引</param>
        /// <param name="func">下项公式</param>
        /// <param name="iniv">初值</param>
        /// <returns></returns>
        public static float GenericSeqenceIndexValue(byte index,Func<float,float> func,float iniv = 0) {
            var r = default(float);
            if (index == 0) {
                r = iniv;
            } else {
                var v = index - 1;
                r += func(GenericSeqenceIndexValue((byte)v,func,iniv));
            }
            return r;
        }
        #endregion
    }
}
